"""
校园圈子序列化器
处理帖子、评论、点赞等数据的序列化和反序列化
"""

from rest_framework import serializers
from django.db.models import Count, Q
from .models import Category, Post, PostImage, Comment, Like, Tag, PostTag


class CategorySerializer(serializers.ModelSerializer):
    """
    分类序列化器
    """
    
    post_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Category
        fields = ['id', 'name', 'description', 'icon', 'post_count', 'created_at']
        read_only_fields = ['id', 'created_at']
    
    def get_post_count(self, obj):
        """获取分类下的帖子数量"""
        return obj.posts.filter(status='published').count()


class TagSerializer(serializers.ModelSerializer):
    """
    标签序列化器
    """
    
    class Meta:
        model = Tag
        fields = ['id', 'name', 'color', 'created_at']
        read_only_fields = ['id', 'created_at']


class PostImageSerializer(serializers.ModelSerializer):
    """
    帖子图片序列化器
    """
    
    class Meta:
        model = PostImage
        fields = ['id', 'image', 'order', 'created_at']
        read_only_fields = ['id', 'created_at']


class CommentSerializer(serializers.ModelSerializer):
    """
    评论序列化器
    """
    
    author_nickname = serializers.CharField(source='author.nickname', read_only=True)
    author_avatar = serializers.ImageField(source='author.avatar', read_only=True)
    parent_nickname = serializers.CharField(source='parent.nickname', read_only=True)
    like_count = serializers.SerializerMethodField()
    is_liked = serializers.SerializerMethodField()
    
    class Meta:
        model = Comment
        fields = [
            'id', 'content', 'author', 'author_nickname', 'author_avatar',
            'post', 'parent', 'parent_nickname', 'like_count', 'is_liked',
            'created_at'
        ]
        read_only_fields = ['id', 'author', 'created_at']
    
    def get_like_count(self, obj):
        """获取评论点赞数"""
        return obj.likes.count()
    
    def get_is_liked(self, obj):
        """当前用户是否点赞了该评论"""
        request = self.context.get('request')
        if request and request.user and hasattr(request.user, 'is_authenticated') and request.user.is_authenticated:
            return obj.likes.filter(user=request.user).exists()
        return False
    
    def create(self, validated_data):
        """创建评论时自动设置作者"""
        validated_data['author'] = self.context['request'].user
        return super().create(validated_data)


class PostListSerializer(serializers.ModelSerializer):
    """
    帖子列表序列化器（简化版）
    """
    
    author_nickname = serializers.CharField(source='author.nickname', read_only=True)
    author_avatar = serializers.ImageField(source='author.avatar', read_only=True)
    category_name = serializers.CharField(source='category.name', read_only=True)
    comment_count = serializers.SerializerMethodField()
    like_count = serializers.SerializerMethodField()
    is_liked = serializers.SerializerMethodField()
    tags = TagSerializer(many=True, read_only=True)
    first_image = serializers.SerializerMethodField()
    
    class Meta:
        model = Post
        fields = [
            'id', 'title', 'content', 'author', 'author_nickname', 'author_avatar',
            'category', 'category_name', 'comment_count', 'like_count', 'is_liked',
            'tags', 'first_image', 'is_top', 'status', 'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'author', 'created_at', 'updated_at']
    
    def get_comment_count(self, obj):
        """获取评论数量"""
        return obj.comments.filter(is_hidden=False).count()
    
    def get_like_count(self, obj):
        """获取点赞数量"""
        return obj.likes.count()
    
    def get_is_liked(self, obj):
        """当前用户是否点赞了该帖子"""
        request = self.context.get('request')
        if request and request.user and hasattr(request.user, 'is_authenticated') and request.user.is_authenticated:
            return obj.likes.filter(user=request.user).exists()
        return False
    
    def get_first_image(self, obj):
        """获取第一张图片"""
        first_image = obj.images.filter(order=1).first()
        if first_image:
            return first_image.image.url
        return None


class PostDetailSerializer(serializers.ModelSerializer):
    """
    帖子详情序列化器
    """
    
    author_nickname = serializers.CharField(source='author.nickname', read_only=True)
    author_avatar = serializers.ImageField(source='author.avatar', read_only=True)
    category_name = serializers.CharField(source='category.name', read_only=True)
    comment_count = serializers.SerializerMethodField()
    like_count = serializers.SerializerMethodField()
    is_liked = serializers.SerializerMethodField()
    tags = TagSerializer(many=True, read_only=True)
    images = PostImageSerializer(many=True, read_only=True)
    comments = serializers.SerializerMethodField()
    
    class Meta:
        model = Post
        fields = [
            'id', 'title', 'content', 'author', 'author_nickname', 'author_avatar',
            'category', 'category_name', 'comment_count', 'like_count', 'is_liked',
            'tags', 'images', 'comments', 'is_top', 'status', 'created_at', 'updated_at', 'allow_comment'
        ]
        read_only_fields = ['id', 'author', 'created_at', 'updated_at']
    
    def get_comment_count(self, obj):
        """获取评论数量"""
        return obj.comments.filter(is_hidden=False).count()
    
    def get_like_count(self, obj):
        """获取点赞数量"""
        return obj.likes.count()
    
    def get_is_liked(self, obj):
        """当前用户是否点赞了该帖子"""
        request = self.context.get('request')
        if request and request.user and hasattr(request.user, 'is_authenticated') and request.user.is_authenticated:
            return obj.likes.filter(user=request.user).exists()
        return False
    
    def get_comments(self, obj):
        """获取帖子的评论列表（只返回一级评论）"""
        comments = obj.comments.filter(
            is_hidden=False, 
            parent__isnull=True
        ).order_by('-created_at')[:10]  # 只返回前10条评论
        return CommentSerializer(comments, many=True, context=self.context).data


class PostCreateSerializer(serializers.ModelSerializer):
    """
    帖子创建序列化器
    """
    
    images = PostImageSerializer(many=True, required=False)
    tag_ids = serializers.ListField(
        child=serializers.IntegerField(),
        required=False,
        write_only=True
    )
    
    class Meta:
        model = Post
        fields = [
            'title', 'content', 'category', 'images', 'tag_ids',
            'is_top', 'status', 'allow_comment', 'post_type'
        ]
    
    def create(self, validated_data):
        """创建帖子"""
        images_data = validated_data.pop('images', [])
        tag_ids = validated_data.pop('tag_ids', [])
        
        # 设置作者
        validated_data['author'] = self.context['request'].user
        
        # 创建帖子
        post = Post.objects.create(**validated_data)
        
        # 创建图片
        for i, image_data in enumerate(images_data, 1):
            image_data['order'] = i
            PostImage.objects.create(post=post, **image_data)
        
        # 添加标签
        if tag_ids:
            tags = Tag.objects.filter(id__in=tag_ids)
            for tag in tags:
                PostTag.objects.create(post=post, tag=tag)
        
        return post
    
    def update(self, instance, validated_data):
        """更新帖子"""
        images_data = validated_data.pop('images', [])
        tag_ids = validated_data.pop('tag_ids', [])
        
        # 更新帖子基本信息
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        
        # 更新图片（删除旧的，添加新的）
        instance.images.all().delete()
        for i, image_data in enumerate(images_data, 1):
            image_data['order'] = i
            PostImage.objects.create(post=instance, **image_data)
        
        # 更新标签
        instance.tags.clear()
        if tag_ids:
            tags = Tag.objects.filter(id__in=tag_ids)
            for tag in tags:
                PostTag.objects.create(post=instance, tag=tag)
        
        return instance


class LikeSerializer(serializers.ModelSerializer):
    """
    点赞序列化器
    """
    
    post = serializers.PrimaryKeyRelatedField(queryset=Post.objects.all(), required=False)
    comment = serializers.PrimaryKeyRelatedField(queryset=Comment.objects.all(), required=False)
    
    class Meta:
        model = Like
        fields = ['id', 'user', 'post', 'comment', 'created_at']
        read_only_fields = ['id', 'user', 'created_at']
    
    def create(self, validated_data):
        """创建点赞时自动设置用户"""
        validated_data['user'] = self.context['request'].user
        return super().create(validated_data)
    
    def validate(self, attrs):
        """验证点赞数据"""
        user = self.context['request'].user
        post = attrs.get('post')
        comment = attrs.get('comment')
        
        # 检查是否提供了post或comment
        if not post and not comment:
            raise serializers.ValidationError("必须提供post或comment中的一个")
        
        # 检查是否同时提供了post和comment
        if post and comment:
            raise serializers.ValidationError("不能同时点赞帖子和评论")
        
        # 检查是否已经点赞
        if post:
            if Like.objects.filter(user=user, post=post).exists():
                raise serializers.ValidationError("您已经点赞过这个帖子了")
        elif comment:
            if Like.objects.filter(user=user, comment=comment).exists():
                raise serializers.ValidationError("您已经点赞过这个评论了")
        
        return attrs


class PostSearchSerializer(serializers.Serializer):
    """
    帖子搜索序列化器
    """
    
    keyword = serializers.CharField(max_length=100, required=False)
    category = serializers.IntegerField(required=False)
    tag_ids = serializers.ListField(
        child=serializers.IntegerField(),
        required=False
    )
    author = serializers.IntegerField(required=False)
    sort_by = serializers.ChoiceField(
        choices=['latest', 'popular', 'most_commented'],
        default='latest',
        required=False
    )
    page = serializers.IntegerField(min_value=1, default=1, required=False)
    page_size = serializers.IntegerField(min_value=1, max_value=50, default=10, required=False)
